from django.http import HttpResponse
from django.core.mail import send_mail
from django.views import View
from django.http import JsonResponse
import re, json
from rest_framework.pagination import PageNumberPagination
from redis import StrictRedis
from rest_framework import viewsets
from users.models import User, Address, Area
from users.sers import UserSerializer
from rest_framework.views import APIView
from rest_framework.response import Response
# 导入系统提供的认证函数

from django.contrib.auth import authenticate
# 认证通过返回用户，否则返回空

# 此方法接收 request, username, password, 认证通过返回用户, 否则返回空
from users.sers import UserSerializer, AreaSerializer, AddressSerializer
from users.users_utils import generate_verify_email_url, decode_email_token


# Create your views here.

class RegisterView(View):

    def post(self, request):
        # 1 接收参数 ajax请求 接受的是 body中的 json数据
        # 转换成字典
        data = json.loads(request.body.decode())
        print(data)
        username = data.get('username')
        password = data.get('password')
        password2 = data.get('password2')
        mobile = data.get('mobile')
        sms_code = data.get('sms_code')
        allow = data.get('allow')

        # 2 检验参数
        # 判断参数是否齐全
        if not all([username, password, password2, mobile, sms_code]):
            return JsonResponse({'msg': '缺少必传参数', 'code': 400})
        # 判断用户名是否是 5-20个字符
        # ^ 占位符 ^abc123$
        if not re.match(r'^[a-zA-Z0-9_]{5,20}$', username):
            return JsonResponse({'msg': "请输入5-20个字符的用户名", 'code': 999})
        # 判断密码是否8-20个数字
        if not re.match(r'^[0-9A-Za-z]{8,20}$', password):
            return JsonResponse({'msg': '请输入8-20位的密码', 'code': 999})
        # 判断两次密码是否一致
        if password != password2:
            return JsonResponse({'msg': '两次输入的密码不一致', 'code': 999})
        # 正则判断输入的手机号
        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return JsonResponse({'msg': '手机号码格式不正确', 'code': 999})
        # 验证是否有验证码
        if not sms_code:
            return JsonResponse({'msg': '没有验证码', 'code': 999})
        # 验证是否勾选协议
        if not allow:
            return JsonResponse({'msg': '没有勾选协议', 'code': 999})
        # 判断手机验证码
        client = StrictRedis()
        redis_sms_code = client.get(mobile)
        if redis_sms_code:
            redis_sms_code = redis_sms_code.decode()
        else:
            redis_sms_code = None
        if sms_code == redis_sms_code:
            pass
        else:
            return JsonResponse({'code': '999', 'msg': '短信验证码错误'})
        # 3. 生成用户
        try:
            User.objects.create_user(username=username, password=password, mobile=mobile)
        except Exception as e:
            return JsonResponse({'msg': '注册失败', 'code': 400})
        # 所有操作数据库的地方 都要写 try
        # 4. 返回响应
        return JsonResponse({'msg': 'ok', 'code': 0})


class LoginView(View):
    def post(self, request):
        data = json.loads(request.body.decode())
        print(data)
        username = data.get('username')
        password = data.get('password')
        if not all([username, password]):
            return JsonResponse({'msg': '缺少必传参数', 'code': 400})
            # 判断用户名是否是 5-20个字符
            # ^ 占位符 ^abc123$
        if not re.match(r'^[a-zA-Z0-9_@\.]{5,50}$', username):
            return JsonResponse({'msg': "请输入5-20个字符的用户名", 'code': 999})
            # 判断密码是否8-20个数字
        if not re.match(r'^[0-9A-Za-z]{8,20}$', password):
            return JsonResponse({'msg': '请输入8-20位的密码', 'code': 999})
        try:
            user = User.objects.filter(username=username).first()
            print(user)
        except Exception as e:
            return JsonResponse({'msg': '用户信息不存在', 'code': 999})
        # 3.认证用户
        user = authenticate(request, username=username, password=password)
        if user:  # 认证成功
            return JsonResponse({
                'msg': '登录成功',
                'code': 0,
                'username': user.username,
                'uid': user.id,
                'token': '000'
            })
        else:  # 认证失败
            return JsonResponse({'msg': '密码错误', 'code': 999})
        # if user.check_password(password):
        #     return JsonResponse({
        #         'msg': '登录成功',
        #         'code': 0,
        #         'username': user.username,
        #         'uid': user.id,
        #         'token': '000'
        #     })
        # else:
        #     return JsonResponse({'msg': '密码错误', 'code': 999})


class UsernameCountView(View):
    def get(self, request, username):
        count = User.objects.filter(username=username).count()
        return JsonResponse({'code': '0', 'msg': 'ok', 'count': count})


class MobileCountView(View):
    def get(self, request, mobile):
        count = User.objects.filter(mobile=mobile).count()
        return JsonResponse({'code': '0', 'msg': 'ok', 'count': count})


class UserViewSet(viewsets.ModelViewSet):
    """
    完成产品的增删改查
    """
    queryset = User.objects.all()  # 视图集默认定义了数据,
    serializer_class = UserSerializer  # 优先使用 get_serializer_class 返回的序列化器


class EmailAddView(APIView):
    # 自定义权限类
    # permission_classes = (IsAdminUser,)

    # 1. 获取email验证码的接口
    def post(self, request):
        # 1. 获取数据
        email = request.data.get('email')
        print(email)
        # 2. 校验数据
        pass
        # 3. 保存数据
        user = request.user
        user.email = email
        user.email_active = False
        user.save()
        # 4. 发送认证邮件
        # 4.1 生成token, 作为邮件内容
        verify_email_url = generate_verify_email_url(user.id)
        # 4.2 发送邮件
        send_mail(subject="激活邮件",
                  message='请点击以激活邮件:%s' % verify_email_url,
                  from_email='jhc18902113276@163.com',
                  recipient_list=[user.email])
        pass
        # 5. 返回结果
        return Response({'code': 0, 'msg': '验证邮件发送成功'})


class EmailVerificationView(View):
    def get(self, request):
        token = request.GET.get('token')
        print(token)
        user_id = decode_email_token(token)
        print(user_id)
        if user_id:
            user = User.objects.get(id=user_id)
            user.email_active = True
            user.save()
            return HttpResponse('邮箱已激活')
        else:
            return HttpResponse('token失效')


class NoPageNum(PageNumberPagination):
    page_size_query_param = 'page_size'
    page_size = 1000


class AreaViewSet(viewsets.ModelViewSet):
    """
    完成产品的增删改查
    """
    queryset = Area.objects.all()  # 视图集默认定义了数据,
    serializer_class = AreaSerializer  # 优先使用 get_serializer_class 返回的序列化器

    pagination_class = NoPageNum
    # http://127.0.0.1:8000/area/?parent=1    所有的省
    # http://127.0.0.1:8000/area/?parent=110000    110000所有的市
    # http://127.0.0.1:8000/area/?parent=110100    110100所有的区

    # 指定过滤字段, 不设置, 过滤功能不起效
    filter_fields = ('parent', 'id')


class AddressViewSet(viewsets.ModelViewSet):
    """
    完成产品的增删改查
    """
    queryset = Address.objects.filter(is_deleted=False)  # 视图集默认定义了数据,
    serializer_class = AddressSerializer  # 优先使用 get_serializer_class 返回的序列化器

    pagination_class = NoPageNum
    # 生成url的情况
    # GET  http://127.0.0.1:8000/address/?id=n     过滤属于自己的地址
    # POST http://127.0.0.1:8000/address/  body{"user":"uid","":""}    增加新地址
    # PUT  http://127.0.0.1:8000/address/pk/  body{"":"","":""}    修改地址
    # DELETE  http://127.0.0.1:8000/address/pk/     删除地址

    # 指定过滤字段, 不设置, 过滤功能不起效
    filter_fields = ('user',)
